/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

 #include "mock_topology_drivers.h"
 #include <cstring>
 #include <cstdlib>
 
 using namespace devmon::test;
 
 // C 风格的函数包装器，用于符合 driver_abi.h 中定义的函数指针类型。
 extern "C" {
 driver_handle_t create_mock_device(void* service, const char* name) {
     try {
         if (service == nullptr) {
             return nullptr;
         }
 
         auto* device = new mock_topology_device();
         device->set_object_name(name);
         device->set_service(static_cast<mc::engine::service*>(service));
         return (void*)device;
     } catch (const std::exception& e) {
         elog("Error creating mock_topology_device: ${error}", ("error", e.what()));
         return nullptr;
     }
 }
 
 status_t init_mock_device(driver_handle_t device, void* csr_object, void* connector) {
     auto* device_object  = static_cast<mock_topology_device*>(device);
     auto* csr_object_ptr = static_cast<mc::mutable_dict*>(csr_object);
     auto* connector_ptr  = static_cast<mc::dict*>(connector);
 
     if (!device_object->init(*csr_object_ptr, *connector_ptr)) {
         return STATUS_ERROR;
     }
     return STATUS_OK;
 }
 
 status_t start_mock_device(driver_handle_t device) {
     auto* device_object = static_cast<mock_topology_device*>(device);
     return device_object->start() ? STATUS_OK : STATUS_ERROR;
 }
 
 status_t stop_mock_device(driver_handle_t device) {
     auto* device_object = static_cast<mock_topology_device*>(device);
     return device_object->stop() ? STATUS_OK : STATUS_ERROR;
 }
 } // extern "C"
 
 namespace devmon::test {
 
 device_driver_t* mock_topology_driver_factory::create(const std::string& device_name) {
     device_driver_t* device_driver = static_cast<device_driver_t*>(malloc(sizeof(device_driver_t)));
     if (device_driver == nullptr) {
         return nullptr;
     }
 
     char* name_copy = static_cast<char*>(malloc(device_name.size() + 1));
     if (name_copy == nullptr) {
         free(device_driver);
         return nullptr;
     }
     std::memcpy(name_copy, device_name.c_str(), device_name.size() + 1);
 
     new (device_driver) device_driver_t{.device_name = name_copy,
                                         .ctor        = create_mock_device,
                                         .init        = init_mock_device,
                                         .start       = start_mock_device,
                                         .stop        = stop_mock_device};
 
     return device_driver;
 }
 
 } // namespace devmon::test
 
 MC_REFLECT(devmon::test::mock_topology_device, ((m_system_id, "SystemId")));
 